package com.douqu.game.battle.server;

import com.alibaba.fastjson.JSONObject;
import com.bean.core.util.TimeUtils;
import com.douqu.game.battle.controller.sprite.PlayerController;
import com.douqu.game.battle.util.MsgUtils;
import com.douqu.game.core.e.E_BattleDetailType;
import com.douqu.game.core.entity.activity.DirectEndData;
import com.douqu.game.core.entity.battle.BattleInitParam;
import com.douqu.game.core.entity.battle.BattleInitParamInstance;
import com.douqu.game.core.entity.battle.BattleInitParamWorldMap;
import com.douqu.game.core.factory.CodeFactory;
import com.douqu.game.core.factory.ConstantFactory;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.protobuf.SGCommonProto.E_BATTLE_TYPE;
import com.douqu.game.core.util.CoreUtils;
import com.douqu.game.core.util.LogUtils;
import com.douqu.game.core.web.request.MajorBattleParam;

import java.rmi.RemoteException;

/**
 * Created by bean on 2017/7/27.
 */
public class BattleInitInfo {

    /**
     * 过期时间
     */
    public final static int OVERDUE_TIME = 30 * 1000;

    /**
     * 过期后处理成AI的时间
     */
    public final static int OVERDUE_TO_AI_TIME = 15 * 1000;

    private String battleId;

    private BattleInitTarget player;

    private BattleInitTarget target;

    private E_BATTLE_TYPE battleType;

    private E_BattleDetailType battleDetailType;

    private long createTime;

    private BattleInitParam param;


    public BattleInitInfo(JSONObject jsonObject)
    {
        battleId = jsonObject.getString(CodeFactory.KEY_BATTLE_ID);
        int battleTypeInt = jsonObject.getInteger(CodeFactory.KEY_BATTLE_TYPE);
        battleType = SGCommonProto.E_BATTLE_TYPE.forNumber(battleTypeInt);
        int battleDetailTypeInt = jsonObject.getInteger(CodeFactory.KEY_BATTLE_DETAIL_TYPE);
        battleDetailType = E_BattleDetailType.forNumber(battleDetailTypeInt);
        createTime = DataFactory.currentTime;

        String playerIndex = jsonObject.getString(CodeFactory.KEY_PLAYER_INDEX);
        int playerServerId = jsonObject.getInteger(CodeFactory.KEY_PLAYER_SERVER_ID);
        int playerFC = jsonObject.containsKey(CodeFactory.KEY_PLAYER_FC) ? jsonObject.getInteger(CodeFactory.KEY_PLAYER_FC) : 0;
        String targetIndex = jsonObject.getString(CodeFactory.KEY_TARGET_INDEX);
        int targetServerId = jsonObject.getInteger(CodeFactory.KEY_TARGET_SERVER_ID);
        int targetFC = jsonObject.containsKey(CodeFactory.KEY_TARGET_FC) ? jsonObject.getInteger(CodeFactory.KEY_TARGET_FC) : 0;
        String targetName = jsonObject.getString(CodeFactory.KEY_TARGET_NAME);

        String paramStr = jsonObject.getString(CodeFactory.KEY_PARAM);
        if(!CoreUtils.isNullOrEmpty(paramStr))
        {
            if(battleType == E_BATTLE_TYPE.BATTLE_TYPE_WORLD_MAP)
                param = JSONObject.parseObject(paramStr, BattleInitParamWorldMap.class);
            else if(battleType == E_BATTLE_TYPE.BATTLE_TYPE_INSTANCE)
                param = JSONObject.parseObject(paramStr, BattleInitParamInstance.class);
            else
                param = JSONObject.parseObject(paramStr, BattleInitParam.class);
        }

        if(battleDetailType.isPlayerBattle())
        {
            player = new BattleInitTarget(playerServerId, playerIndex, false, null, playerFC);
            target = new BattleInitTarget(targetServerId, targetIndex, !battleDetailType.isBothPlayer(), targetName, targetFC);
        }
        else
        {
            player = new BattleInitTarget(playerServerId, playerIndex, true, null, playerFC);
            target = new BattleInitTarget(targetServerId, targetIndex, true, targetName, targetFC);
        }
    }

    public boolean isOverdue()
    {
        return DataFactory.currentTime - createTime >= OVERDUE_TIME;
    }

    /**
     * 有AI战的过期后要自动变化AI战(目前只是大地图和阵营战)
     * @return
     */
    public boolean isOverdueToAI()
    {
        if(battleType == E_BATTLE_TYPE.BATTLE_TYPE_WORLD_MAP || battleType == E_BATTLE_TYPE.BATTLE_TYPE_SPAN_CAMP)
            return DataFactory.currentTime - createTime >= OVERDUE_TO_AI_TIME;
        else
            return false;
    }

    public boolean isExist(String objectIndex)
    {
        return objectIndex.equals(player.getPlayerIndex()) || objectIndex.equals(target.getPlayerIndex());
    }

    public BattleInitTarget getBattleInitTarget(String playerIndex)
    {
        if(playerIndex.equals(player.getPlayerIndex()))
            return player;

        if(playerIndex.equals(target.getPlayerIndex()))
            return target;

        return null;
    }


    public void ready(String objectIndex)
    {
        if(player.getPlayerIndex().equals(objectIndex))
            player.setReady(true);
        else if(target.getPlayerIndex().equals(objectIndex))
            target.setReady(true);
    }

    public boolean isReady()
    {
        return player.isReady() && target.isReady();
    }

    public void initPlayerData(PlayerController data)
    {
        if(player.getPlayerIndex().equals(data.getObjectIndex()))
        {
            player.setPlayer(data);
        }
        else if(target.getPlayerIndex().equals(data.getObjectIndex()))
        {
            target.setPlayer(data);
        }
    }

    public String getTargetPlayerIndex()
    {
        switch (battleDetailType)
        {
            case PVP_AI_OFFICIAL_RANK:
                return target.getPlayerIndex().split(ConstantFactory.UNDERLINE)[2];
            case PVP_AI_MAJOR:
                MajorBattleParam param = new MajorBattleParam(target.getPlayerIndex());
                return param.getObjectIndex();
//            case PVP_WORLD_MAP:
//            case PVP_DATA_WORLD_MAP:
//                return target.getPlayerIndex().substring(0, target.getPlayerIndex().lastIndexOf(ConstantFactory.UNDERLINE));
            default:
                return target.getPlayerIndex();
        }
    }


    /**
     * 处理过期的战斗
     * @return
     */
    public boolean checkOverdueToAI()
    {
        if(!isOverdueToAI())
            return false;

        if(player.isReady() && target.isReady())
            return false;

        //如果是玩家对玩家的类型，则未准备的那一方玩家变成AI，如果双方都未准备，则是完全的AI战
        //如果是玩家对AI的类型，若玩家未准备，则变成完全的AI战
        //若本来就是AI对AI，则是异常情况
        //双方都是AI的不会进这个方法来

        LogUtils.warn("玩家一直没来创建战斗，现在开始检测是否转向AI战 -> " + battleDetailType);
        if(player.isReady())
        {
            //player准备好了,target还未准备
            LogUtils.info("player准备了，target未准备");
            target.setReady(true);

            if(battleDetailType == E_BattleDetailType.PVP_WORLD_MAP)
                battleDetailType = E_BattleDetailType.PVP_DATA_WORLD_MAP;
            else if(battleDetailType == E_BattleDetailType.PVP_SPAN_CAMP)
                battleDetailType = E_BattleDetailType.PVP_DATA_SPAN_CAMP;

            //发送Create消息给双方
            MsgUtils.createPlayerBattle(this);

            return true;
        }
        else
        {
            //target有可能是玩家也有可能是AI
            if(target.isReady())
            {
                player.setReady(true);

                LogUtils.info("player没有准备的情况,当有战斗类型 -> " + battleDetailType);

                switch (battleDetailType)
                {
                    case PVP_WORLD_MAP:
                        battleDetailType = E_BattleDetailType.PVP_DATA_WORLD_MAP;//交换player和target
                        BattleInitTarget temp = player;
                        player = target;
                        target = temp;
                        LogUtils.info("交换player和target, 转为 -> " + battleDetailType);
                        MsgUtils.createPlayerBattle(this);
                        break;
                    case PVE_WORLD_MAP:
                        battleDetailType = E_BattleDetailType.DATA_WORLD_MAP_PVE;
                        LogUtils.info("转为 -> " + battleDetailType);
                        MsgUtils.createDataBattle(this);
                        break;
                    case PVP_DATA_WORLD_MAP:
                        battleDetailType = E_BattleDetailType.DATA_WORLD_MAP_PVP;
                        LogUtils.info("转为 -> " + battleDetailType);
                        MsgUtils.createDataBattle(this);
                        break;

                    case PVP_SPAN_CAMP:
                        battleDetailType = E_BattleDetailType.PVP_DATA_SPAN_CAMP;//交换player和target
                        temp = player;
                        player = target;
                        target = temp;
                        LogUtils.info("交换player和target, 转为 -> " + battleDetailType);
                        MsgUtils.createPlayerBattle(this);
                        break;

                    case PVE_SPAN_CAMP:
                    case PVP_DATA_SPAN_CAMP:
                        //获取MatchBaseInfo对象，发送给活动服直接结算
                        try {
                            LogUtils.info("阵营战直接结算");
                            GameServer.getInstance().getIMainServer().directEndBattle(new DirectEndData(battleDetailType.getCode(), player.getServerId(), player.getPlayerIndex(), target.getServerId(), target.getPlayerIndex(), target.getPlayerName(), param));
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                        break;
                }
            }
            else
            {
                LogUtils.info("双方都未准备，当前战斗类型 -> " + battleDetailType);
                //双方都未准备
                if(battleType == E_BATTLE_TYPE.BATTLE_TYPE_WORLD_MAP)
                {
                    switch (battleDetailType)
                    {
                        case PVE_WORLD_MAP:
                            battleDetailType = E_BattleDetailType.DATA_WORLD_MAP_PVE;
                            LogUtils.info("转为 -> " + battleDetailType);
                            MsgUtils.createDataBattle(this);
                            break;
                        case PVP_WORLD_MAP:
                        case PVP_DATA_WORLD_MAP:
                            battleDetailType = E_BattleDetailType.DATA_WORLD_MAP_PVP;
                            LogUtils.info("转为 -> " + battleDetailType);
                            MsgUtils.createDataBattle(this);
                            break;
                    }
                }
                else if(battleType == E_BATTLE_TYPE.BATTLE_TYPE_SPAN_CAMP)
                {
                    //告诉主服直接计算结果
                    try {
                        LogUtils.info("阵营战直接结算");
                        GameServer.getInstance().getIMainServer().directEndBattle(new DirectEndData(battleDetailType.getCode(), player.getServerId(), player.getPlayerIndex(), target.getServerId(), target.getPlayerIndex(), target.getPlayerName(), param));
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return true;
    }


//    private MatchBaseInfo directEndCampBattle()
//    {
//        if(battleDetailType == E_BattleDetailType.PVE_SPAN_CAMP)
//        {
//            DirectEndData directEndData = new DirectEndData();
//            directEndData.setBattleDetailType(battleDetailType.getCode());
//            directEndData.setPlayerIndex(player.getPlayerIndex());
//            directEndData.setPlayerServerId(player.getServerId());
//            directEndData.setInitParam(param);
//
//            CampRobotConfig robotConfig = DataFactory.getInstance().getGameObject(DataFactory.CAMP_ROBOT_KEY, Integer.parseInt(target.getPlayerIndex()));
//            MatchBaseInfo targetInfo = new MatchBaseInfo(robotConfig, 0);
//            targetInfo.setServerId(target.getServerId());
//            if(!CoreUtils.isNullOrEmpty(target.getPlayerName()))
//                targetInfo.setName(target.getPlayerName());
//
//            directEndData.setTargetInfo(targetInfo);
//            directEndData.setPlayerWin(player.getFc() > targetInfo.getFc());
//
//            GameServer.getInstance().getIMainServer().directEndBattle(directEndData);
//        }
//        else if(battleDetailType == E_BattleDetailType.PVP_SPAN_CAMP || battleDetailType == E_BattleDetailType.PVP_DATA_SPAN_CAMP)
//        {
//            try {
//                Player sourcePlayer = GameServer.getInstance().getIMainServer().getPlayer(player.getPlayerIndex());
//                Player targetPlayer = GameServer.getInstance().getIMainServer().getPlayer(target.getPlayerIndex());
//                if(sourcePlayer != null && targetPlayer != null)
//                {
//                    DirectEndData directEndData = new DirectEndData();
//                    directEndData.setBattleDetailType(battleDetailType.getCode());
//                    directEndData.setPlayerIndex(player.getPlayerIndex());
//                    directEndData.setPlayerServerId(player.getServerId());
//                    directEndData.setInitParam(param);
//
//                    MatchBaseInfo targetInfo = new MatchBaseInfo(targetPlayer, target.getServerId());
//                    directEndData.setTargetInfo(targetInfo);
//
//                    directEndData.setPlayerWin(player.getFc() > targetPlayer.fc);
//
//                    GameServer.getInstance().getIMainServer().directEndBattle(directEndData);
//                }
//            } catch (RemoteException e) {
//                e.printStackTrace();
//            }
//        }
//        else
//            return null;
//    }



    public String getBattleId() {
        return battleId;
    }

    public void setBattleId(String battleId) {
        this.battleId = battleId;
    }

    public BattleInitTarget getPlayer() {
        return player;
    }

    public void setPlayer(BattleInitTarget player) {
        this.player = player;
    }

    public BattleInitTarget getTarget() {
        return target;
    }

    public void setTarget(BattleInitTarget target) {
        this.target = target;
    }

    public E_BATTLE_TYPE getBattleType() {
        return battleType;
    }

    public void setBattleType(E_BATTLE_TYPE battleType) {
        this.battleType = battleType;
    }

    public E_BattleDetailType getBattleDetailType() {
        return battleDetailType;
    }

    public void setBattleDetailType(E_BattleDetailType battleDetailType) {
        this.battleDetailType = battleDetailType;
    }

    public BattleInitParam getParam() {
        return param;
    }

    public void setParam(BattleInitParam param) {
        this.param = param;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof BattleInitInfo)) return false;

        BattleInitInfo that = (BattleInitInfo) o;

        if (battleId != null ? !battleId.equals(that.battleId) : that.battleId != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return battleId != null ? battleId.hashCode() : 0;
    }

    @Override
    public String toString() {
        return "{" +
                "battleId='" + battleId + '\'' +
                ", createTime=" + TimeUtils.getFormatTime(createTime) +
                ", source=" + player +
                ", target=" + target +
                ", battleType=" + battleType +
                ", battleDetailType=" + battleDetailType +
                '}';
    }




}
